package controllers;

import play.*;
import play.mvc.*;

import java.text.SimpleDateFormat;
import java.util.*;

import models.*;

@With(Secure.class)
/**
 * @author Benitez Guillaume
 * controlleur lié aux actions sur les fmpa quinquennales
 */
public class FMPAQuinquennals extends Controller {

	/**
	 * Instancie des variables de session(session.put())
	 * Met ces variables dans des variables de rendu(render.args())
	 */
	@Before
	static void setConnectedUser() {
		if(Security.isConnected()) {
			if(!session.contains("agent_fullname")){
				Agent agent = Agent.find("nomUtilisateur", Security.connected()).first();
				Fonction gestFonct=Fonction.find("id_fonction like ?", "FONCT").first();
				Fonction gestTer=Fonction.find("id_fonction like ?", "TERRI").first();
				Fonction admin=Fonction.find("id_fonction like ?", "ADM").first();
				Fonction chef_CIS=Fonction.find("id_fonction like ?", "RCIS").first();
				Fonction formateur=Fonction.find("id_fonction like ?", "FOR").first();
				List<CIS> centres=CIS.find("responsable.id like ?", agent.id).fetch();
				boolean resp=!centres.isEmpty();
				/*
				 * Compte le nombre d'autorisation en attente pour les CIS où l'agent est responsable
				 * et l'ajoute à une variable de session et de rendu.
				 */
				List<Candidat> listeCandidats=new ArrayList<Candidat>();
				if(agent.fonction.contains(chef_CIS) || resp){
					Iterator<CIS> i=centres.iterator();
					while(i.hasNext()){
						List<Candidat> cand=Candidat.find("agent.cis.id like ? and etatCandid.id_etatcandid like ?", i.next().id, "AAUT").fetch();
						listeCandidats.addAll(cand);
					}
					session.put("nb_demande_auto", listeCandidats.size());
					renderArgs.put("nb_demande_auto", Integer.parseInt(session.get("nb_demande_auto")));
				}
				/*
				 * Compte le nombre de validations et d'annulations en attente et l'ajoute à une variable de session et de rendu.
				 */
				if(agent.fonction.contains(admin) || agent.fonction.contains(gestFonct)){
					long nbValidAdmin=Candidat.count("etatCandid.id_etatcandid like ? and demandeAnnulation is not true", "AVAL");
					long nbAnnulAdmin=Candidat.count("demandeAnnulation is true");
					session.put("nb_demande_valid_admin", nbValidAdmin);
					renderArgs.put("nb_demande_valid_admin", Integer.parseInt(session.get("nb_demande_valid_admin")));
					session.put("nb_demande_annul_admin", nbAnnulAdmin);
					renderArgs.put("nb_demande_annul_admin", Integer.parseInt(session.get("nb_demande_annul_admin")));
				}
				/*
				 * Compte le nombre de validations et d'annulations en attente pour le groupement dont l'agent est responsable
				 * et l'ajoute à une variable de session et de rendu.
				 */
				if(agent.fonction.contains(gestTer)){
					long nbValidTerri=Candidat.count("etatCandid.id_etatcandid like ? and stage.structure.responsable like ? and demandeAnnulation is not true", "AVAL", agent);
					long nbAnnulTerri=Candidat.count("demandeAnnulation is true and stage.structure.responsable.id like ? and etatCandid.id_etatcandid not like ? or etatCandid.nom not like ?", agent.id, "ANN", "REF");
					session.put("nb_demande_valid_terri", nbValidTerri);
					renderArgs.put("nb_demande_valid_terri", Integer.parseInt(session.get("nb_demande_valid_terri")));
					session.put("nb_demande_annul_terri", nbAnnulTerri);
					renderArgs.put("nb_demande_annul_terri", Integer.parseInt(session.get("nb_demande_annul_terri")));
				}
				
				/*
				 * Création des variables de session
				 */
				
				/*
				 * groupementResp_id représente l'id du groupement de l'agent si celui-ci est le responsable
				 * Sinon l'id du groupement auquel il appartient s'il possède la fonction gestionnaireTerritorial
				 */
				Groupement gpmt=Groupement.find("responsable like ?", agent).first();
				if(gpmt!=null){
					session.put("groupementResp_id", gpmt.id);
				}
				else if(agent.fonction.contains(gestTer)){
					session.put("groupementResp_id", agent.cis.groupement.id);
				}
				
				int aujourdhui=Calendar.getInstance().get(Calendar.YEAR);
				session.put("nomUtilisateur", agent.nomUtilisateur);
				session.put("anneeEnCours", aujourdhui);
				session.put("agent_id", agent.id);
				session.put("agent_niv", agent.niv.niv);
				session.put("agent_cis", agent.cis);
				session.put("agent_grpt", agent.cis.groupement);
				session.put("chef_CIS", agent.fonction.contains(chef_CIS));
				session.put("agent_email", agent.email);
				session.put("agent_fullname", agent.fullname());
				session.put("agent_responsable", resp);
				session.put("agent_grade", agent.grade.toString());
				session.put("gestionnaireFonct", (agent.fonction.contains(gestFonct)));
				session.put("gestionnaireTerri", agent.fonction.contains(gestTer));
				session.put("formateur", agent.fonction.contains(formateur));
				session.put("admin", agent.fonction.contains(admin));
				session.put("CISService", agent.cis.nom);
				/*
				 * Compte le nombre de validations en attente pour les fmpa et l'ajoute à une variable de session et de rendu.
				 */
				if(agent.fonction.contains(admin) || agent.fonction.contains(gestFonct)){
					long nbValidAdmin=FMPA.count("etat.id_etatfmpa like ?", "ATVAL");
					session.put("nb_valid_fmpa", nbValidAdmin);
					renderArgs.put("nb_valid_fmpa", Integer.parseInt(session.get("nb_valid_fmpa")));
				}else if(agent.fonction.contains(gestTer)){
					long nbValidTerri=FMPA.count("etat.id_etatfmpa like ? and cis.groupement.nom like ?", "ATVAL", session.get("agent_grpt"));
					session.put("nb_valid_fmpa", nbValidTerri);
					renderArgs.put("nb_valid_fmpa", Integer.parseInt(session.get("nb_valid_fmpa")));
				}else if(agent.fonction.contains(chef_CIS) || resp){
					long nbValidCis=FMPA.count("etat.id_etatfmpa like ? and cis.nom like ?", "ATVAL", session.get("CISService"));
					session.put("nb_valid_fmpa", nbValidCis);
					renderArgs.put("nb_valid_fmpa", Integer.parseInt(session.get("nb_valid_fmpa")));
				}
				System.out.println(session.get("nb_valid_fmpa"));
				/*
				 * Création des variables de rendu
				 */
				if(session.contains("groupementResp_id")){
					renderArgs.put("groupementResp_id", Long.parseLong(session.get("groupementResp_id")));
				}
				renderArgs.put("anneeEnCours", Integer.parseInt(session.get("anneeEnCours")));
				renderArgs.put("CISService", session.get("CISService"));
				renderArgs.put("agent_niv", Integer.parseInt(session.get("agent_niv")));
				renderArgs.put("agent_grpt", session.get("agent_grpt"));
				renderArgs.put("chef_CIS", session.get("chef_CIS").equals("true"));
				renderArgs.put("admin", session.get("admin").equals("true"));
				renderArgs.put("formateur", session.get("formateur").equals("true"));
				renderArgs.put("agent_email", session.get("agent_email"));
				renderArgs.put("agent_fullname", session.get("agent_fullname"));
				renderArgs.put("agent_responsable", session.get("agent_responsable").equals("true"));
				renderArgs.put("agent_grade", session.get("agent_grade"));
				renderArgs.put("gestionnaireFonct", session.get("gestionnaireFonct").equals("true"));
				renderArgs.put("gestionnaireTerri", session.get("gestionnaireTerri").equals("true"));
				if(agent.niv.id != 0){
					session.put("agent_for", agent.niv);
					renderArgs.put("agent_for", session.get("agent_for"));
				}
				Calendar c=Calendar.getInstance();
				renderArgs.put("Annee", c.get(Calendar.YEAR));
			}
			else{
				/*
				 * Création des variables de rendu si les variables de session existent
				 */
				if(session.contains("nb_demande_valid_terri") || session.contains("nb_demande_annul_terri")){
					renderArgs.put("nb_demande_valid_terri", Integer.parseInt(session.get("nb_demande_valid_terri")));
					renderArgs.put("nb_demande_annul_terri", Integer.parseInt(session.get("nb_demande_annul_terri")));
				}
				if(session.contains("nb_demande_auto")){
					renderArgs.put("nb_demande_auto", Integer.parseInt(session.get("nb_demande_auto")));
				}
				if(session.contains("nb_demande_valid_admin") || session.contains("nb_demande_annul_admin")){
					renderArgs.put("nb_demande_valid_admin", Integer.parseInt(session.get("nb_demande_valid_admin")));
					renderArgs.put("nb_demande_annul_admin", Integer.parseInt(session.get("nb_demande_annul_admin")));
				}
				if(session.contains("nb_demande_auto")){
					renderArgs.put("nb_demande_auto", Integer.parseInt(session.get("nb_demande_auto")));
				}
				renderArgs.put("anneeEnCours", Integer.parseInt(session.get("anneeEnCours")));
				renderArgs.put("CISService", session.get("CISService"));
				renderArgs.put("agent_niv", Integer.parseInt(session.get("agent_niv")));
				renderArgs.put("agent_grpt", session.get("agent_grpt"));
				renderArgs.put("chef_CIS", session.get("chef_CIS").equals("true"));
				renderArgs.put("admin", session.get("admin").equals("true"));
				renderArgs.put("formateur", session.get("formateur").equals("true"));
				renderArgs.put("agent_email", session.get("agent_email"));
				renderArgs.put("agent_fullname", session.get("agent_fullname"));
				renderArgs.put("agent_responsable", session.get("agent_responsable").equals("true"));
				renderArgs.put("agent_grade", session.get("agent_grade"));
				renderArgs.put("gestionnaireFonct", session.get("gestionnaireFonct").equals("true"));
				renderArgs.put("gestionnaireTerri", session.get("gestionnaireTerri").equals("true"));
				renderArgs.put("agent_for", session.get("agent_for"));
				if(session.contains("nb_valid_fmpa")){
					renderArgs.put("nb_valid_fmpa", Integer.parseInt(session.get("nb_valid_fmpa")));
				}
				if(session.contains("groupementResp_id")){
					renderArgs.put("groupementResp_id", Long.parseLong(session.get("groupementResp_id")));
				}
				Calendar c=Calendar.getInstance();
				renderArgs.put("Annee", c.get(Calendar.YEAR));
			}
		}
	}

	/**
	 * Fonction appelée pour récupérer les informations nécessaires à la liste des fmpa sap.
	 * Appelle le fichier html éponyme
	 */
	public static void listFMPA(String annee){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		int anneebis=Integer.decode(annee);
		List<Participation> participations;
		Iterator<Participation> itPart;
		Participation part;
		List<FMPAQuinquennal> fmpaQs=new ArrayList<FMPAQuinquennal>();
		List<FMPA> fmpas=new ArrayList<FMPA>();
		FMPAQuinquennal fmpaQ;
		Date aujourdhui = new Date();
		CIS cis=CIS.find("nom like ?", session.get("CISService")).first();
		boolean isFMPA=false;
		boolean isFMPAQ=false;
		Thematique sap=Thematique.find("id_thematique like ?", "SAP").first();
		//récupération des FMPA SAP en fonction de la fonction
		if(session.get("gestionnaireFonct").equals("true") || session.get("admin").equals("true")){
			fmpas=FMPA.find("thematique like ?", sap).fetch();
		}
		else{
			if(session.get("gestionnaireTerri").equals("true")){
				fmpas=FMPA.find("cis.groupement like ? and thematique like ?",cis.groupement, sap).fetch();
			}
			else if(session.get("agent_responsable").equals("true")){
				//récupère la liste des cis dont l'agent est responsable
				List<CIS> listCis=CIS.find("responsable.id like ?", Long.decode(session.get("agent_id"))).fetch();
				CIS c;
				if(!listCis.contains(cis)){
					listCis.add(cis);
				}
				//pour chaque cis, récupère les fmpa SAP
				List<FMPA> listFmpa;
				Iterator<CIS> itCis=listCis.iterator();
				while(itCis.hasNext()){
					c=itCis.next();
					listFmpa=FMPA.find("thematique like ? and cis like ?", sap, c).fetch();
					fmpas.addAll(listFmpa);
				}
			}
			//récupère les fmpa du centre pour les agents qui ont les droits de chef de centre
			List<FMPA> fmpabis=FMPA.find("cis like ? and thematique like ?",cis, sap).fetch();
			Iterator<FMPA> itf=fmpabis.iterator();
			FMPA f;
			while(itf.hasNext()){
				f=itf.next();
				if(!fmpas.contains(f)){
					fmpas.add(f);
				}
			}
			//récupère les participations de l'agent pour ajouter les fmpa correspondantes à la liste
			participations=Participation.find("agent.id like ? and role.id_rolefmpa like ? and fmpa.cis not like ? and fmpa.thematique like ?", Long.decode(session.get("agent_id")), "FORMA", cis, sap).fetch();
			itPart=participations.iterator();
			while(itPart.hasNext()){
				part=itPart.next();
				fmpas.add(part.fmpa);
			}
		}
		//récupération des FMPA quinquennales en fonction de la fonction
		if(session.get("gestionnaireFonct").equals("true") || session.get("admin").equals("true")){
			fmpaQs=FMPAQuinquennal.find("annee like ?", anneebis).fetch();
		}
		else{
			if(session.get("gestionnaireTerri").equals("true")){
				fmpaQs=FMPAQuinquennal.find("fmpa.cis.groupement like ? and annee like ?",cis.groupement, anneebis).fetch();
			}
			else if(session.get("agent_responsable").equals("true")){
				//récupère la liste des cis dont l'agent est responsable
				List<CIS> listCis=CIS.find("responsable.id like ?", Long.decode(session.get("agent_id"))).fetch();
				CIS c;
				if(!listCis.contains(cis)){
					listCis.add(cis);
				}
				//pour chaque cis, récupère les fmpa SAP_Quinquennal
				List<FMPAQuinquennal> listFmpa;

				Iterator<CIS> itCis=listCis.iterator();
				while(itCis.hasNext()){
					c=itCis.next();
					listFmpa=FMPAQuinquennal.find("fmpa.cis like ? and annee like ?", c, anneebis).fetch();
					fmpaQs.addAll(listFmpa);
				}
			}
			//récupère les fmpa du centre pour les agents qui ont les droits de chef de centre
				List<FMPAQuinquennal> fmpaQuinquennals=FMPAQuinquennal.find("fmpa.cis like ? and annee like ?",cis, anneebis).fetch();
				Iterator<FMPAQuinquennal> itf=fmpaQuinquennals.iterator();
				FMPAQuinquennal f;
				while(itf.hasNext()){
					f=itf.next();
					if(!fmpaQs.contains(f)){
						fmpaQs.add(f);
					}
				}
			//récupère les participations de l'agent pour ajouter les fmpa correspondantes à la liste
			participations=Participation.find("agent.id like ? and role.id_rolefmpa like ? and fmpa.cis not like ? and fmpa.thematique.id_thematique like ?", Long.decode(session.get("agent_id")), "FORMA", cis, "SAPQ").fetch();
			itPart=participations.iterator();
			while(itPart.hasNext()){
				part=itPart.next();
				fmpaQ=FMPAQuinquennal.find("fmpa like ?", part.fmpa).first();
				if(fmpaQ.annee==anneebis){
					fmpaQs.add(fmpaQ);
				}
			}
		}
		//booléen pour l'affichage des tableaux
		isFMPAQ=(fmpaQs.size()!=0);
		isFMPA=(fmpas.size()!=0);
		//la liste des séquences pour l'année selectionnée
		List<Sequence> listSeq=Sequence.find("annee like ? order by nom", anneebis).fetch();
		//crée la liste des années composée de l'année courante, des deux années passées et de l'année suivante
		Calendar c=Calendar.getInstance();
		int A=c.get(Calendar.YEAR);
		List<Integer> annees=new ArrayList<Integer>();
		annees.add(A+2);
		annees.add(A+1);
		annees.add(A);
		annees.add(A-1);
		annees.add(A-2);
		render(fmpaQs, aujourdhui, isFMPA, fmpas, isFMPAQ, listSeq, anneebis, annees);
	}

	/**
	 * Fonction appelée pour récupérer les informations nécessaires à la création d'une nouvelle fmpa quinquennale.
	 * Appelle le fichier html éponyme qui permet de créer une fmpa quinquennale.
	 */
	public static void newQuinquenalForm(){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		List<CIS> centres;
		Thematique thematique;
		List<Duree> durees;
		CIS cis=CIS.find("nom like ?", session.get("CISService")).first();

		//récupération de la liste des CIS ou service, des thématiques, des durées
		centres=CIS.find("order by nom").fetch();
		thematique=Thematique.find("id_thematique like ? order by nom", "SAPQ").first();
		durees=Duree.findAll();
		long idCis=cis.id;
		//récupère la liste des séquences de l'année en cours
		Calendar c=Calendar.getInstance();
		List<Sequence> listSeq=Sequence.find("annee like ? order by nom", c.get(Calendar.YEAR)).fetch();
		//récupère les thèmes SAP
		List<SousThematique> sousThematiques=SousThematique.find("thematique.id_thematique like ? order by nom", "SAP").fetch();
		render(centres, thematique, durees, idCis, listSeq, sousThematiques);
	}

	/**
	 * Crée la fmpa avec les informations du formulaire. Vérifie que les informations obligatoires ont été renseignées et sauvegarde la fmpa.
	 * @param cis : id du cis
	 * @param date
	 * @param sousThematique : intitulé du thême de la formation
	 * @param description
	 * @param duree : id d'objet durée
	 * @param observation
	 */
	public static void newQuinquenalSave(long cis, Date date, int annee, String description, long duree, String observation){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		EtatFMPA etat=EtatFMPA.find("id_etatfmpa like ?", "PREVU").first();

		//récupération des objets par les id
		Duree dureeObj=Duree.findById(duree);
		CIS cisObj=CIS.findById(cis);
		Thematique thematiqueObj=Thematique.find("id_thematique like ?", "SAPQ").first();
		Agent a=Agent.findById(Long.decode(session.get("agent_id")));
		RoleFMPA role=RoleFMPA.find("nom like ?", "formateur").first();

		//récupération de la liste des CIS ou service, des thématiques, des durées
		List<CIS> centres=CIS.find("order by nom").fetch();
		Thematique thematique=Thematique.find("id_thematique like ? order by nom", "SAPQ").first();
		List<Duree> durees=Duree.findAll();
		long idCis=cis;
		//récupère la liste des séquences de l'année
		List<Sequence> listSeq=Sequence.find("annee like ? order by nom", annee).fetch();
		//récupère les thèmes SAP
		List<SousThematique> sousThematiques=SousThematique.find("thematique.id_thematique like ? order by nom", "SAP").fetch();

		//création de l'objet FMPA
		FMPA fmpa;
		String sousThematique="";
		Iterator<Sequence> itSeq=listSeq.iterator();
		boolean bool;
		Sequence seq;
		//pour chaque séquence, regarde si la case associée du formulaire a été cochée
		//si la case est cochée, ajoute le nom du thème de la séquence
		while(itSeq.hasNext()){
			seq=itSeq.next();
			bool=params.get(seq.id.toString(), boolean.class);
			if(bool){
				if(sousThematique.equals("")){
					sousThematique=sousThematique+seq.theme.nom;
				}else{
					sousThematique=sousThematique+", "+seq.theme.nom;
				}
			}
		}
		//crée la fmpa et ajoute l'agent logué sur la fmpa en tant que formateur
		fmpa=new FMPA(cisObj,date,thematiqueObj,sousThematique,description,dureeObj,observation,etat);
		Participation p=new Participation(a,fmpa,role);
		fmpa.addParticipant(p);
		//crée la fmpa quinquennale associée
		FMPAQuinquennal fmpaQ=new FMPAQuinquennal(fmpa,annee);
		itSeq=listSeq.iterator();
		//pour chaque séquence, regarde si la case associée du formulaire a été cochée
		//si la case est cochée, ajoute la séquence associée
		while(itSeq.hasNext()){
			seq=itSeq.next();
			bool=params.get(seq.id.toString(), boolean.class);
			if(bool){
				fmpaQ.add(seq);
			}
		}

		//vérifie que tous les champs requis sont renseignés et sauvegarde en cas de vérification réussie
		//Affichage d'un bandeau en fonction du résultat
		if(annee==0){
			flash.error("Information manquante: année de prise en compte");
			render("@newQuinquenalForm", fmpaQ, centres, thematique, durees, idCis, listSeq, sousThematiques);
		}else{
			validation.valid(fmpa);
			if(validation.hasErrors()){
				//affiche un message d'erreur personnalisé en fonction du champ manquant
				play.data.validation.Error error=validation.required(dureeObj).error;
				if(error!=null){
					flash.error(error.message("durée"));
				}
				error=validation.required(date).error;
				if(error!=null){
					flash.error(error.message("date"));
				}
				//rapelle le formulaire en gardant les variables entrées par l'utilisateur
				render("@newQuinquenalForm", fmpaQ, centres, thematique, durees, idCis, listSeq, sousThematiques);
			}else{
				//sauve la fmpa
				//affiche un bandeau d'erreur si un des string est trop long pour être stocké en BDD
				try {
					fmpa.save();
				} catch (Exception e) {
					flash.error("Thème ou observation trop longue");
					render("@newQuinquenalForm", fmpaQ, centres, thematique, durees, idCis, listSeq, sousThematiques);
				}
				//vérifie que les informations spécifiques aux fmpa quinquennals sont correctes
				//sauve la fmpa en cas de succès
				validation.valid(fmpaQ);
				if(validation.hasErrors()){
					flash.error("Il y a une erreur dans le formulaire");
					render("@newQuinquenalForm", fmpaQ, centres, thematique, durees, idCis, listSeq, sousThematiques);
				}else{
					fmpaQ.save();
				}
			}
		}
		//affiche un bandeau de succès et ouvre un nouveau formulaire
		flash.success("La FMPA a bien été enregistré.");
		newQuinquenalForm();
	}

	/**
	 * permet de récupérer les informations de la fmpa ainsi que les listes nécessaires à l'ajout des agents
	 * Appelle le fichier html éponyme qui permet de visualiser les détails de la fmpa et de gérer la liste des participants
	 * @param id : id de la fmpa quinquennale
	 */
	public static void detailFMPA(long id){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		//récupération de la fmpa, de la liste des participants
		//ainsi que la liste des cis, des agents du cis et des rôles
		FMPAQuinquennal fmpaQ=FMPAQuinquennal.findById(id);
		List<Participation> participants=Participation.find("fmpa_id like ?", fmpaQ.fmpa.id).fetch();
		List<CIS> ciss=CIS.find("order by nom").fetch();
		List<Agent> agents=Agent.find("cis like ? order by nom", fmpaQ.fmpa.cis).fetch();
		List<RoleFMPA> roles=RoleFMPA.findAll();
		boolean isParticipant=(participants.size()!=0);
		//récupère les id des éléments à afficher dans les select
		long idCis=fmpaQ.fmpa.cis.id;
		RoleFMPA r=RoleFMPA.find("id_rolefmpa like ?", "FORME").first();
		long idForme=r.id;
		renderArgs.put("isParticipant", isParticipant);
		List<Sequence> listSeq=Sequence.find("annee like ? order by nom", fmpaQ.annee).fetch();
		render(fmpaQ,participants,ciss,agents,roles,idCis, listSeq, idForme);
	}

	/**
	 * récupère les informations de la fmpa quinquennale et les listes nécessaires.
	 * Appelle le fichier html éponyme qui permet de modifier une fmpa quinquennale.
	 * @param id : id de la fmpa quinquennale
	 */
	public static void modifFMPAForm(long id){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		else{
			List<CIS> centres;
			List<Thematique> thematiques;
			List<Duree> durees;

			//récupération de la liste des CIS ou service, des thématiques, des durées
			FMPAQuinquennal fmpaQ=FMPAQuinquennal.findById(id);
			centres=CIS.find("order by nom").fetch();
			thematiques=Thematique.find("order by nom").fetch();
			durees=Duree.findAll();
			//formatage de la date pour affichage
			SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
			String date=sdf.format(fmpaQ.fmpa.date);
			//récupération des id
			long idCis=fmpaQ.fmpa.cis.id;
			long idDuree=fmpaQ.fmpa.duree.id;
			List<Sequence> listSeq=Sequence.find("order by nom").fetch();
			List<SousThematique> sousThematiques=SousThematique.find("thematique.id_thematique like ? order by nom", "SAP").fetch();
			render(fmpaQ, centres, thematiques, durees, date, idCis, idDuree, listSeq, sousThematiques);
		}
	}

	/**
	 * récupère les informations du formulaire, les compare avec les informations de la fmpa originale et sauvegarde les nouvelles informations.
	 * @param cis : id du cis
	 * @param date
	 * @param thematique : id de la thématique
	 * @param Theme : intitulé du thème de la formation
	 * @param description
	 * @param duree : id de la durée
	 * @param observation
	 * @param fmpa : id de la fmpa quinquennale
	 */
	public static void modifFMPA(long cis, Date date, int annee, long thematique,String Theme, String description, long duree, String observation, long fmpa){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		FMPAQuinquennal fmpaObj=FMPAQuinquennal.findById(fmpa);
		Sequence s;
		boolean coche;
		//application des modifications sur l'objet fmpa
		CIS cisObj=CIS.findById(cis);
		Thematique themaObj=Thematique.findById(thematique);
		Duree dureeObj=Duree.findById(duree);
		if(cisObj==null||themaObj==null||dureeObj==null||annee==0){
			flash.error("Il y a une erreur dans le formulaire");
			modifFMPAForm(fmpa);
		}else{
			List<Sequence> listSeq=Sequence.find("annee like ?", annee).fetch();
			String sousThematique="";
			Iterator<Sequence> itSeq=listSeq.iterator();
			//pour chaque séquence, regarde si la case associée du formulaire a été cochée
			//si la case est cochée, ajoute le nom du thème de la séquence
			while(itSeq.hasNext()){
				s=itSeq.next();
				coche=params.get(s.id.toString(), boolean.class);
				if(coche){
					if(sousThematique.equals("")){
						sousThematique=sousThematique+s.theme.nom;
					}else{
						sousThematique=sousThematique+", "+s.theme.nom;
					}
				}
			}
			//si l'année a changé, vide la liste des séquences
			fmpaObj.fmpa.sousThematique=sousThematique;
			if(annee!=fmpaObj.annee){
				fmpaObj.sequences.clear();
			}
			//pour chaque séquence, regarde si la case associée du formulaire a été cochée
			//si la case est cochée et que la séquence n'était pas présente, la rajoute
			//si la case est décochée et que la séquence était présente, l'enlève
			itSeq=listSeq.iterator();
			while(itSeq.hasNext()){
				s=itSeq.next();
				coche=params.get(s.id.toString(), boolean.class);
				if(coche&&!fmpaObj.contientSequence(s)){
					fmpaObj.sequences.add(s);
				}else if(fmpaObj.contientSequence(s)&&!coche){
					fmpaObj.sequences.remove(s);
				}
			}
			//compare chaque champ à l'original et la modifie si nécessaire
			if(!fmpaObj.fmpa.cis.id.equals(cis)){fmpaObj.fmpa.cis=cisObj;}
			if(!fmpaObj.fmpa.date.equals(date)){fmpaObj.fmpa.date=date;}
			if(fmpaObj.annee!=annee&&annee!=0){fmpaObj.annee=annee;}
			if(!fmpaObj.fmpa.thematique.id.equals(thematique)){fmpaObj.fmpa.thematique=themaObj;}
			if(!fmpaObj.fmpa.description.equals(description)){fmpaObj.fmpa.description=description;}
			if(!fmpaObj.fmpa.duree.id.equals(duree)){fmpaObj.fmpa.duree=dureeObj;}
			if(!fmpaObj.fmpa.observation.equals(observation)){fmpaObj.fmpa.observation=observation;}

			//vérifie que tous les champs requis sont renseignés et sauvegarde en cas de vérification réussie
			//Affichage d'un bandeau en fonction du résultat
			validation.valid(fmpaObj.fmpa);
			if(validation.hasErrors()){
				flash.error("Il y a une erreur dans le formulaire");
				modifFMPAForm(fmpa);
			}else{
				validation.valid(fmpaObj);
				if(validation.hasErrors()){
					flash.error("Il y a une erreur dans le formulaire");
					modifFMPAForm(fmpa);
				}else{

					//sauvegarde de l'objet
					try {
						fmpaObj.fmpa.save();
					} catch (Exception e) {
						flash.error("Observation trop longue");
						modifFMPAForm(fmpa);
					}
					fmpaObj.save();
					flash.success("Les modifications ont été enregistrées.");
					detailFMPA(fmpa);
				}
			}
		}
	}

	/**
	 * récupère les informations du formulaire, crée une nouvelle participation, vérifie que toutes les informations ont été renseignées et sauvegarde l'objet
	 * @param agent : id de l'agent
	 * @param role : id du role
	 * @param fmpa : id de la fmpa
	 * @param fmpaQ : id de la fmpa quinquennale
	 */
	public static void newParticipantSave(long agent, long role, long fmpa, long fmpaQ){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		//récupère l'agent, le rôle et la fmpa avec les identifiants
		Agent agentObj=Agent.findById(agent);
		FMPA fmpaObj=FMPA.findById(fmpa);
		RoleFMPA roleObj=RoleFMPA.findById(role);
		Participation test=Participation.find("fmpa like ? and agent like ? and role like ?", fmpaObj, agentObj, roleObj).first();
		if(test!=null){
			flash.error("cet agent fait déjà parti de la liste");
			detailFMPA(fmpaQ);
		}else{
			//création de l'objet participation
			Participation p=new Participation(agentObj,fmpaObj,roleObj);
			//ajout à la liste des participations à la fmpa
			fmpaObj.participants.add(p);
			//test de validité de la participation
			//affichage d'un bandeau en fonction de la validité et retour à la page de détail de la fmpa
			validation.valid(p);
			if(validation.hasErrors()){
				flash.error("aucun agent n'a été sélectionné");
				detailFMPA(fmpaQ);
			}else{
				p.save();
				fmpaObj.save();
				flash.success("un nouveau participant a été ajouté.");
				detailFMPA(fmpaQ);
			}
		}
	}

	/**
	 * Récupère la liste des cis en fonction des droits de la cession courante
	 * Appelle le fichier html éponyme.
	 */
	public static void statForm(){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		List<CIS> ciss;
		CIS cis=CIS.find("nom like ?", session.get("CISService")).first();
		//récupère la liste des cis visibles de l'agent en fonction de sa fonction
		if(session.get("gestionnaireFonct").equals("true") || session.get("admin").equals("true")){
			ciss=CIS.find("order by nom").fetch();
		}
		else if(session.get("gestionnaireTerri").equals("true")){
			ciss=CIS.find("groupement like ? order by nom", cis.groupement).fetch();
		}
		else if(session.get("agent_responsable").equals("true")){
			ciss=CIS.find("responsable.id like ?", Long.decode(session.get("agent_id"))).fetch();
			if(!ciss.contains(cis)){
				ciss.add(cis);
			}
		}
		else{
			ciss=new ArrayList<CIS>();
			ciss.add(cis);
		}
		long idCis=cis.id;
		//crée la liste des années composée de l'année courante, des deux années passées et de l'année suivante
		List<Integer> annees=new ArrayList<Integer>();
		Calendar c=Calendar.getInstance();
		int x=c.get(Calendar.YEAR);
		annees.add(x+1);
		annees.add(x);
		annees.add(x-1);
		annees.add(x-2);
		render(ciss, idCis, annees, x);
	}

	/**
	 * Calcule les informations nécessaires aux statistiques sur les formateurs.
	 * Appelle le fichier html éponyme qui permet de présenter l'information.
	 * @param cis : id du cis
	 */
	public static void resumeCIS(long cis, int annee){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		//récupération du cis et des agents du cis
		CIS centre=CIS.findById(cis);
		List<Agent> agents=Agent.find("cis like ? order by nom", centre).fetch();

		//création des variables
		Agent a;
		int sommeSAP;
		int totalCis=0;
		Participation participation;
		List<Participation> participations;
		Iterator<Participation> itParticipation;
		Iterator<Agent> it;
		StatistiqueAgent stat;
		List<StatistiqueAgent> stats;
		FMPAQuinquennal fmpaQ;
		Calendar c=Calendar.getInstance();

		//création d'un itérateur pour le parcours de la liste
		it=agents.iterator();
		stats=new ArrayList<StatistiqueAgent>();
		//parcours la liste des agents pour calculer les statistiques
		while(it.hasNext()){
			a=it.next();
			//création d'un objet statistique lié à l'agent a
			stat=new StatistiqueAgent(a);
			//création d'un itérateur sur la liste des participations de l'agent
			participations=Participation.find("agent like ? and role.id_rolefmpa like ? and fmpa.thematique.id_thematique like ? and fmpa.etat.id_etatfmpa like ?", a, "FORMA","SAP", "TERMI").fetch();
			itParticipation=participations.iterator();
			sommeSAP=0;
			//parcours de toutes les participations en tant que formateur de l'agent a
			//calcul de la somme du temps passé à la formation
			while(itParticipation.hasNext()){
				participation=itParticipation.next();
				c.setTime(participation.fmpa.date);
				if(c.get(Calendar.YEAR)==annee){
					sommeSAP=sommeSAP+participation.fmpa.duree.minutes;
				}
			}
			//création d'un itérateur sur la liste des participations de l'agent
			participations=Participation.find("agent like ? and role.id_rolefmpa like ? and fmpa.thematique.id_thematique like ? and fmpa.etat.id_etatfmpa like ?", a, "FORMA","SAPQ", "TERMI").fetch();
			itParticipation=participations.iterator();
			//parcours de toutes les participations en tant que formateur de l'agent a
			//calcul de la somme du temps passé à la formation
			while(itParticipation.hasNext()){
				participation=itParticipation.next();
				fmpaQ=FMPAQuinquennal.find("fmpa like ?", participation.fmpa).first();
				if(fmpaQ.annee==annee){
					sommeSAP=sommeSAP+participation.fmpa.duree.minutes;
				}
			}
			if(sommeSAP>0){
				//ajout de la somme calculée à l'objet statistique
				stat.add("Somme", ""+(sommeSAP)/60+" h "+(sommeSAP)%60+" min");
				//ajout de l'objet statistique à la liste
				stats.add(stat);
				totalCis=totalCis+sommeSAP;
			}
		}
		String totalString=""+totalCis/60+" h "+totalCis%60+" min";
		render(stats, totalString);
	}

	public static void listAgents(String cis){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		CIS centre=CIS.find("nom like ?", cis).first();
		List<CIS> ciss;
		//récupère la liste des cis visibles de l'agent en fonction de sa fonction
		if(session.get("gestionnaireFonct").equals("true") || session.get("admin").equals("true")){
			ciss=CIS.find("order by nom").fetch();
		}
		else if(session.get("gestionnaireTerri").equals("true")){
			ciss=CIS.find("groupement like ? order by nom", centre.groupement).fetch();
		}
		else if(session.get("agent_responsable").equals("true")){
			ciss=CIS.find("responsable.id like ?", Long.decode(session.get("agent_id"))).fetch();
			if(!ciss.contains(centre)){
				ciss.add(centre);
			}
		}
		else{
			ciss=new ArrayList<CIS>();
			ciss.add(centre);
		}
		long idCis=centre.id;
		//crée la liste des années composée de l'année courante, des deux années passées et de l'année suivante
		List<Integer> annees=new ArrayList<Integer>();
		Calendar c=Calendar.getInstance();
		int x=c.get(Calendar.YEAR);
		annees.add(x+1);
		annees.add(x);
		annees.add(x-1);
		annees.add(x-2);
		render(ciss, idCis, annees, x);
	}

	public static void listSequence(int annee){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		List<Sequence> listSeq=Sequence.find("annee like ?", annee).fetch();
		render(listSeq);
	}

	public static void listSequenceCoche(long id, int annee){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		FMPAQuinquennal fmpaQ=FMPAQuinquennal.findById(id);
		List<Sequence> listSeq=Sequence.find("annee like ?", annee).fetch();
		render(listSeq, fmpaQ);
	}

	/**
	 * Calcule les informations nécessaires aux statistiques sur les formés.
	 * Appelle le fichier html éponyme qui permet de présenter l'information.
	 * @param cis : id du cis
	 */
	public static void syntheseAgents(long cis, int annee){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		//récupération du cis et des agents du cis
		CIS centre=CIS.findById(cis);
		List<Agent> agents=Agent.find("cis like ? order by nom", centre).fetch();

		//création des variables
		Agent a;
		Participation participation;
		List<Participation> participations;
		Iterator<Participation> itParticipation;
		Iterator<Agent> it;
		StatistiqueAgent stat;
		List<StatistiqueAgent> stats;
		FMPAQuinquennal fmpaQuinquenal;
		Sequence sequence;
		List<Sequence> sequences=Sequence.find("annee like ? order by nom", annee).fetch();
		Iterator<Sequence> itSeq;

		//création d'un itérateur pour le parcours de la liste
		it=agents.iterator();
		stats=new ArrayList<StatistiqueAgent>();
		//parcours la liste des agents pour calculer les statistiques
		while(it.hasNext()){
			a=it.next();
			//création d'un objet statistique lié à l'agent a
			stat=new StatistiqueAgent(a);
			//initialisation des valeurs à false
			itSeq=sequences.iterator();
			while(itSeq.hasNext()){
				sequence=itSeq.next();
				stat.add(sequence.nom, "false");
			}
			//création d'un itérateur sur la liste des participations de l'agent
			participations=Participation.find("agent like ? and role.id_rolefmpa like ? and fmpa.thematique.id_thematique like ? and fmpa.etat.id_etatfmpa like ? and valide is true", a, "FORME","SAPQ", "TERMI").fetch();
			itParticipation=participations.iterator();
			//parcours de toutes les participations en tant que formé de l'agent a
			//modification de la séquence en true si validée
			while(itParticipation.hasNext()){
				participation=itParticipation.next();
				fmpaQuinquenal=FMPAQuinquennal.find("fmpa like ?", participation.fmpa).first();
				if(fmpaQuinquenal.annee==annee){
					itSeq=sequences.iterator();
					while(itSeq.hasNext()){
						sequence=itSeq.next();
						if(fmpaQuinquenal.contientSequence(sequence)){
							SimpleDateFormat s=new SimpleDateFormat("dd MMMM yyyy");
							stat.add(sequence.nom, "faite le "+s.format(fmpaQuinquenal.fmpa.date));
						}
					}
				}
			}
			//ajout de l'objet statistique à la liste
			stats.add(stat);
		}
		render(stats,sequences);
	}

	/**
	 * Récupère les informations de la fmpa quinquenale.
	 * Appelle le fichier html éponyme qui permet de générer des pv au format A4
	 * @param idFMPA : id de la fmpa quinquennale
	 */
	public static void pv(long idFMPA){
		FMPAQuinquennal fmpa=FMPAQuinquennal.findById(idFMPA);
		List<Participation> listForm=Participation.find("fmpa like ? and role.id_rolefmpa like ?", fmpa.fmpa, "FORME").fetch();
		List<Participation> listFormateur=Participation.find("fmpa like ? and role.id_rolefmpa like ?", fmpa.fmpa, "FORMA").fetch();
		Iterator<Participation> itPart=listForm.iterator();
		Participation part;
		int nbValid=0;
		//parcours la liste des formés pour avoir le nombre de participations validées
		while(itPart.hasNext()){
			part=itPart.next();
			if(part.valide){
				nbValid++;
			}
		}
		render(fmpa, listForm, listFormateur, nbValid);
	}

	/**
	 * Récupère les informations de la fmpa quinquenale.
	 * Appelle le fichier html éponyme qui permet de générer des pv au format A4
	 * @param idFMPA : id de la fmpa quinquennale
	 */
	public static void pvList(long cis, int annee){
		//vérification des droits d'accès
		if(session.get("agent_responsable").equals("false")&&session.get("chef_CIS").equals("false")&&session.get("gestionnaireTerri").equals("false")&&session.get("gestionnaireFonct").equals("false")&&session.get("formateur").equals("false")&&session.get("admin").equals("false")){
			render("@accessDenied");
		}
		//récupération du cis et des agents du cis
		CIS centre=CIS.findById(cis);
		List<Agent> agents=Agent.find("cis like ? order by nom", centre).fetch();

		//création des variables
		Agent a;
		Participation participation;
		List<Participation> participations;
		Iterator<Participation> itParticipation;
		Iterator<Agent> it;
		StatistiqueAgent stat;
		List<StatistiqueAgent> stats;
		FMPAQuinquennal fmpaQuinquenal;
		Sequence sequence;
		List<Sequence> sequences=Sequence.find("annee like ? order by nom", annee).fetch();
		Iterator<Sequence> itSeq;

		//création d'un itérateur pour le parcours de la liste
		it=agents.iterator();
		stats=new ArrayList<StatistiqueAgent>();
		//parcours la liste des agents pour calculer les statistiques
		while(it.hasNext()){
			a=it.next();
			//création d'un objet statistique lié à l'agent a
			stat=new StatistiqueAgent(a);
			//initialisation des valeurs à false
			itSeq=sequences.iterator();
			while(itSeq.hasNext()){
				sequence=itSeq.next();
				stat.add(sequence.nom, "false");
			}
			//création d'un itérateur sur la liste des participations de l'agent
			participations=Participation.find("agent like ? and role.id_rolefmpa like ? and fmpa.thematique.id_thematique like ? and fmpa.etat.id_etatfmpa like ? and valide is true", a, "FORME","SAPQ", "TERMI").fetch();
			itParticipation=participations.iterator();
			//parcours de toutes les participations en tant que formé de l'agent a
			//modification de la séquence en true si validée
			while(itParticipation.hasNext()){
				participation=itParticipation.next();
				fmpaQuinquenal=FMPAQuinquennal.find("fmpa like ?", participation.fmpa).first();
				if(fmpaQuinquenal.annee==annee){
					itSeq=sequences.iterator();
					while(itSeq.hasNext()){
						sequence=itSeq.next();
						if(fmpaQuinquenal.contientSequence(sequence)){
							SimpleDateFormat s=new SimpleDateFormat("dd MM yyyy");
							stat.add(sequence.nom, "faite le "+s.format(fmpaQuinquenal.fmpa.date));
						}
					}
				}
			}
			//ajout de l'objet statistique à la liste
			stats.add(stat);
		}
		render(stats,sequences, centre, annee);
	}
}
